home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-ALPH.{_4 / ATOMIC.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  3KB  |  113 lines

  1. #ifndef _ALPHA_ATOMIC_H
  2. #define _ALPHA_ATOMIC_H
  3.  
  4. /*
  5.  * Atomic operations that C can't guarantee us.  Useful for
  6.  * resource counting etc...
  7.  *
  8.  * But use these as seldom as possible since they are much slower
  9.  * than regular operations.
  10.  */
  11.  
  12. #ifdef __SMP__
  13. typedef struct { volatile int counter; } atomic_t;
  14. #else
  15. typedef struct { int counter; } atomic_t;
  16. #endif
  17.  
  18. #define ATOMIC_INIT(i)    ( (atomic_t) { (i) } )
  19.  
  20. #define atomic_read(v)        ((v)->counter)
  21. #define atomic_set(v,i)        ((v)->counter = (i))
  22.  
  23. /*
  24.  * Make sure gcc doesn't try to be clever and move things around
  25.  * on us. We need to use _exactly_ the address the user gave us,
  26.  * not some alias that contains the same information.
  27.  */
  28. #define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x)
  29.  
  30. /*
  31.  * To get proper branch prediction for the main line, we must branch
  32.  * forward to code at the end of this object's .text section, then
  33.  * branch back to restart the operation.
  34.  */
  35.  
  36. extern __inline__ void atomic_add(int i, atomic_t * v)
  37. {
  38.     unsigned long temp;
  39.     __asm__ __volatile__(
  40.     "1:    ldl_l %0,%1\n"
  41.     "    addl %0,%2,%0\n"
  42.     "    stl_c %0,%1\n"
  43.     "    beq %0,2f\n"
  44.     ".section .text2,\"ax\"\n"
  45.     "2:    br 1b\n"
  46.     ".previous"
  47.     :"=&r" (temp), "=m" (__atomic_fool_gcc(v))
  48.     :"Ir" (i), "m" (__atomic_fool_gcc(v)));
  49. }
  50.  
  51. extern __inline__ void atomic_sub(int i, atomic_t * v)
  52. {
  53.     unsigned long temp;
  54.     __asm__ __volatile__(
  55.     "1:    ldl_l %0,%1\n"
  56.     "    subl %0,%2,%0\n"
  57.     "    stl_c %0,%1\n"
  58.     "    beq %0,2f\n"
  59.     ".section .text2,\"ax\"\n"
  60.     "2:    br 1b\n"
  61.     ".previous"
  62.     :"=&r" (temp), "=m" (__atomic_fool_gcc(v))
  63.     :"Ir" (i), "m" (__atomic_fool_gcc(v)));
  64. }
  65.  
  66. /*
  67.  * Same as above, but return the result value
  68.  */
  69. extern __inline__ long atomic_add_return(int i, atomic_t * v)
  70. {
  71.     long temp, result;
  72.     __asm__ __volatile__(
  73.     "1:    ldl_l %0,%1\n"
  74.     "    addl %0,%3,%0\n"
  75.     "    mov %0,%2\n"
  76.     "    stl_c %0,%1\n"
  77.     "    beq %0,2f\n"
  78.     ".section .text2,\"ax\"\n"
  79.     "2:    br 1b\n"
  80.     ".previous"
  81.     :"=&r" (temp), "=m" (__atomic_fool_gcc(v)), "=&r" (result)
  82.     :"Ir" (i), "m" (__atomic_fool_gcc(v)));
  83.     return result;
  84. }
  85.  
  86. extern __inline__ long atomic_sub_return(int i, atomic_t * v)
  87. {
  88.     long temp, result;
  89.     __asm__ __volatile__(
  90.     "1:    ldl_l %0,%1\n"
  91.     "    subl %0,%3,%0\n"
  92.     "    mov %0,%2\n"
  93.     "    stl_c %0,%1\n"
  94.     "    beq %0,2f\n"
  95.     ".section .text2,\"ax\"\n"
  96.     "2:    br 1b\n"
  97.     ".previous"
  98.     :"=&r" (temp), "=m" (__atomic_fool_gcc(v)), "=&r" (result)
  99.     :"Ir" (i), "m" (__atomic_fool_gcc(v)));
  100.     return result;
  101. }
  102.  
  103. #define atomic_dec_return(v) atomic_sub_return(1,(v))
  104. #define atomic_inc_return(v) atomic_add_return(1,(v))
  105.  
  106. #define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
  107. #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
  108.  
  109. #define atomic_inc(v) atomic_add(1,(v))
  110. #define atomic_dec(v) atomic_sub(1,(v))
  111.  
  112. #endif /* _ALPHA_ATOMIC_H */
  113.